/*
 * @lc app=leetcode.cn id=36 lang=cpp
 * @lcpr version=30204
 *
 * [36] 有效的数独
 */

// @lcpr-template-start
using namespace std;
#include <algorithm>
#include <array>
#include <bitset>
#include <climits>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// @lcpr-template-end
// @lc code=start
class Solution {
 public:
  bool isValidSudoku(vector<vector<char>>& board) {
    // 定义三个数组分别用于记录行、列和小方块中的数字是否出现过
    vector<unordered_set<char>> rows(9), cols(9), blocks(9);

    // 遍历整个数独
    for (int i = 0; i < 9; ++i) {
      for (int j = 0; j < 9; ++j) {
        char num = board[i][j];
        if (num == '.') continue;  // 跳过空格

        // 计算当前数字属于哪个小方块 行*3 + 列
        int blockIndex = (i / 3) * 3 + (j / 3);

        // 检查当前数字是否已经在对应的行、列或小方块中出现过
        if (rows[i].count(num) || cols[j].count(num) ||
            blocks[blockIndex].count(num)) {
          return false;  // 如果出现重复，返回 false
        }

        // 将当前数字加入对应的行、列和小方块的记录中
        rows[i].insert(num);
        cols[j].insert(num);
        blocks[blockIndex].insert(num);
      }
    }

    return true;  // 如果没有发现重复，返回 true
  }
};
// @lc code=end

/*
// @lcpr case=start
//
[["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]\n
// @lcpr case=end

// @lcpr case=start
//
[["8","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]\n
// @lcpr case=end

 */
